package com.wsg.dep.seq;

import com.wsg.dep.core.ProcessingSequenceBarrier;
import com.wsg.dep.core.SequenceBarrier;
import com.wsg.dep.core.WaitStrategy;
import com.wsg.dep.core.event.DataProvider;
import com.wsg.dep.core.event.EventPoller;
import com.wsg.dep.util.Utils;

import java.util.Arrays;
import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;

/**
 *
 */
public abstract class AbstractSequencer implements Sequencer {

    /**
     * 这是一个静态的原子引用字段更新器，用于对 AbstractSequencer 类中的 gatingSequences 字段进行原子更新操作，以保证在多线程环境下对该字段的更新是线程安全的。
     */
    private static final AtomicReferenceFieldUpdater<AbstractSequencer, Sequence[]> SEQUENCE_UPDATER =
            AtomicReferenceFieldUpdater.newUpdater(AbstractSequencer.class, Sequence[].class, "gatingSequences");

    /**
     * 环形队列内存大小
     */
    protected final int bufferSize;
    /**
     * 等待策略
     */
    protected final WaitStrategy waitStrategy;
    /**
     * 序列号，从-1开始
     */
    protected final Sequence cursor = new Sequence(Sequencer.INITIAL_CURSOR_VALUE);
    /**
     * 门控序列，volatile 关键字保证了该数组在多线程环境下的可见性。
     */
    protected volatile Sequence[] gatingSequences = new Sequence[0];


    /**
     * 构造方法
     * @param bufferSize 缓存大小
     * @param waitStrategy 等待策略
     */
    public AbstractSequencer(int bufferSize, WaitStrategy waitStrategy)
    {
        Utils.bufferSizeCheck(bufferSize);
        this.bufferSize = bufferSize;
        this.waitStrategy = waitStrategy;
    }

    /**
     * 获取游标
     * @return
     */
    @Override
    public final long getCursor()
    {
        return cursor.get();
    }

    /**
     * 获取缓存大小
     * @return
     */
    @Override
    public final int getBufferSize()
    {
        return bufferSize;
    }

    /**
     * 新增序列
     * @param gatingSequences 新增的序列
     */
    @Override
    public final void addGatingSequences(Sequence... gatingSequences)
    {
        SequenceGroups.addSequences(this, SEQUENCE_UPDATER, this, gatingSequences);
    }

    /**
     * 删除序列
     * @param sequence 删除的序列
     * @return
     */
    @Override
    public boolean removeGatingSequence(Sequence sequence)
    {
        return SequenceGroups.removeSequence(this, SEQUENCE_UPDATER, sequence);
    }


    /**
     * 获取添加到当前环形缓冲区的所有门控序列中的最小序列值。
     *
     * @return 如果没有添加任何序列，则返回当前的游标序列值。
     */
    @Override
    public long getMinimumSequence()
    {
        return Utils.getMinimumSequence(gatingSequences, cursor.get());
    }


    /**
     * 创建一个新的SequenceBarrier，
     * 供EventProcessor（事件处理器）使用，用于跟踪从环形缓冲区中哪些消息是可供读取的。
     *
     *
     * @param sequencesToTrack 传入的sequencesToTrack参数表示新创建的屏障将等待的所有序列。
     * @return 环形缓冲区中哪些消息是可供读取的
     * @see SequenceBarrier
     */
    @Override
    public SequenceBarrier newBarrier(Sequence... sequencesToTrack)
    {
        return new ProcessingSequenceBarrier(this, waitStrategy, cursor, sequencesToTrack);
    }



    /**
     * Creates an event poller for this sequence that will use the supplied data provider and
     * gating sequences.
     *
     * @param dataProvider    The data source for users of this event poller
     * @param gatingSequences Sequence to be gated on.
     * @return A poller that will gate on this ring buffer and the supplied sequences.
     */
    @Override
    public <T> EventPoller<T> newPoller(DataProvider<T> dataProvider, Sequence... gatingSequences)
    {
        return EventPoller.newInstance(dataProvider, this, new Sequence(), cursor, gatingSequences);
    }

    @Override
    public String toString()
    {
        return "AbstractSequencer{" +
                "waitStrategy=" + waitStrategy +
                ", cursor=" + cursor +
                ", gatingSequences=" + Arrays.toString(gatingSequences) +
                '}';
    }
    
}
